/**
 * Copyright (c) 2006-2012, JGraph Ltd
 */
/**
 * 为给定的编辑器UI和容器构造一个新的工具栏。
 * 工具栏为图形编辑器提供各种工具按钮和菜单选项。
 *
 * @param {Object} editorUi - 管理工具栏的编辑器UI实例
 * @param {HTMLElement} container - 工具栏的DOM容器元素
 */
function Toolbar(editorUi, container) {
    // 编辑器UI实例，用于管理工具栏与主编辑器的交互
    this.editorUi = editorUi;
    // 工具栏的DOM容器元素，所有工具按钮都将添加到此容器中
    this.container = container;
    // 静态元素数组，存储不应被移除的DOM节点
    this.staticElements = [];
    // 初始化工具栏
    this.init();

    // 全局手势处理器，用于隐藏当前显示的菜单
    this.gestureHandler = mxUtils.bind(this, function (evt) {
        if (this.editorUi.currentMenu != null && mxEvent.getSource(evt) != this.editorUi.currentMenu.div) {
            this.hideMenu();
        }
    });

    mxEvent.addGestureListeners(document, this.gestureHandler);


    // 格式刷的逻辑
    this.editorUi.addListener(
        'selectionChanged',
        mxUtils.bind(this, function (sender, evt) {
            const graph = sender.editor.graph;
            let cells = evt.properties.cells;
            if (graph.painterState && cells.length) {
                const sourceCell = graph.painterState.cell;
                const painterStyle = graph.painterState.painterStyle;

                let targetCells = [];

                if (sourceCell.style.includes('group')) {
                    cells = sourceCell.children;
                }

                if (sourceCell.edge) {
                    targetCells = cells.filter(i => i.edge);
                } else {
                    targetCells = cells;
                }

                graph.model.beginUpdate();
                try {
                    const keys = Object.keys(painterStyle);
                    const values = Object.values(painterStyle);
                    for (var j = 0; j < keys.length; j++) {
                        graph.setCellStyles(keys[j], values[j], targetCells);
                    }

                    sender.fireEvent(new mxEventObject('styleChanged', 'keys', keys, 'values', values, 'cells', targetCells));
                } catch (e) {
                    console.log(e);
                } finally {
                    graph.model.endUpdate();
                }
                sender.actions.get('painter').funct();
            }
        }),
    );
};

/**
 * 下拉箭头的图片资源。
 * 根据客户端是否支持SVG选择不同的图片格式。
 */
Toolbar.prototype.dropdownImage = (!mxClient.IS_SVG) ? IMAGE_PATH + '/dropdown.gif' : '';

/**
 * 下拉箭头的HTML图片元素。
 * 用于在下拉菜单按钮上显示箭头图标。
 */
Toolbar.prototype.dropdownImageHtml = '<img border="0" style="position:absolute;right:4px;top:' +
    ((!EditorUi.compactUi) ? 8 : 6) + 'px;" src="' + Toolbar.prototype.dropdownImage + '" valign="middle"/>';

/**
 * 定义选中按钮的背景色。
 * 当工具栏按钮处于选中状态时使用此背景色。
 */
Toolbar.prototype.selectedBackground = '#d0d0d0';

/**
 * 定义未选中按钮的背景色。
 * 当工具栏按钮处于未选中状态时使用此背景色。
 */
Toolbar.prototype.unselectedBackground = 'none';

/**
 * 包含不应被移除的DOM节点的数组。
 * 这些元素在工具栏重新初始化时会被保留。
 */
Toolbar.prototype.staticElements = null;

/**
 * 添加工具栏元素。
 * 根据屏幕宽度和当前模式动态创建和配置工具栏按钮和菜单。
 */
Toolbar.prototype.init = async function () {
    // 获取屏幕宽度，用于响应式布局
    var sw = screen.width;

    // 考虑初始紧凑模式的宽度调整
    sw -= (screen.height > 740) ? 56 : 0;

    if (!isFzPage) {
        // 绘图组件
        var drawingItems = this.addItems(['drawing-components', '-']);
        // 数据定义
        if (!window.isGuideModel) {
            var defItems = this.addItems(['data-definition', '-']);

            this.editorUi.toggleDrawingMenu(drawingItems[0], defItems[0]);
        }

        // 数据定义
        // this.addItems(['object-structure', '-']);
        // 领域数据
        // this.addItems(['data-domain', '-']);
        // 图片图标
        // this.addItems(['picture-icon', '-']);
        // 保存按钮 gesprite-save
        this.addItems(['save', '-']);
        // this.addSeparator();

        if (sw >= 700) {
            // 创建视图面板菜单，包含视图相关的选项
            var formatMenu = this.addMenu('', mxResources.get('view') + ' (' + mxResources.get('panTooltip') + ')', true, 'viewPanels', null, true);
            this.addDropDownArrow(formatMenu, 'geSprite-formatpanel', 38, 50, -4, -3, 36, -8);
            this.addSeparator();
        }

        // 创建缩放菜单，提供缩放功能控制
        var viewMenu = this.addMenu('', mxResources.get('zoom') + ' (Alt+Mousewheel)', true, 'viewZoom', null, true);
        viewMenu.showDisabled = true;
        viewMenu.style.whiteSpace = 'nowrap';
        viewMenu.style.position = 'relative';
        viewMenu.style.overflow = 'hidden';

        if (EditorUi.compactUi) {
            viewMenu.style.width = '60px';
        } else {
            viewMenu.style.width = '36px';
        }

        if (sw >= 420) {
            this.addSeparator();
            // 创建缩放控制按钮（放大和缩小）
            var elts = this.addItems(['zoomIn', 'zoomOut']);
            elts[0].setAttribute('title', mxResources.get('zoomIn') + ' (' + this.editorUi.actions.get('zoomIn').shortcut + ')');
            elts[1].setAttribute('title', mxResources.get('zoomOut') + ' (' + this.editorUi.actions.get('zoomOut').shortcut + ')');
        }

        // 当缩放比例发生变化时更新标签显示
        this.updateZoom = mxUtils.bind(this, function () {
            viewMenu.innerHTML = Math.round(this.editorUi.editor.graph.view.scale * 100) + '%' +
                this.dropdownImageHtml;

            if (EditorUi.compactUi) {
                viewMenu.getElementsByTagName('img')[0].style.right = '1px';
                viewMenu.getElementsByTagName('img')[0].style.top = '5px';
            }
        });

        this.editorUi.editor.graph.view.addListener(mxEvent.EVENT_SCALE, this.updateZoom);
        this.editorUi.editor.addListener('resetGraphView', this.updateZoom);

        this.addItems(['fullscreen', '-']); // 全屏

        this.addItems(['painter']); // 格式刷

        // 创建撤销和重做按钮
        var elts = this.addItems(['-', 'undo', 'redo']);
        elts[1].setAttribute('title', mxResources.get('undo') + ' (' + this.editorUi.actions.get('undo').shortcut + ')');
        elts[2].setAttribute('title', mxResources.get('redo') + ' (' + this.editorUi.actions.get('redo').shortcut + ')');

        if (sw >= 320) {
            // 创建删除按钮
            var elts = this.addItems(['-', 'delete']);
            elts[1].setAttribute('title', mxResources.get('delete') + ' (' + this.editorUi.actions.get('delete').shortcut + ')');
        }

        if (sw >= 550) {
            this.addItems(['-', 'toFront', 'toBack']);
        }

        if (sw >= 740) {
            this.addItems(['-', 'fillColor']);

            if (sw >= 780) {
                this.addItems(['strokeColor']);

                if (sw >= 820) {
                    this.addItems(['shadow']);
                }
            }
        }

        if (sw >= 400) {
            this.addSeparator();

            const lineTypeMenu = this.addMenu('', mxResources.get('lineType'), false, 'lineType', null, true)
            this.addDropDownArrow(lineTypeMenu, 'geSprite-linetype', 44, 50, 0, 0, 22, -4);

            const arrowTypeMenu = this.addMenu('', mxResources.get('arrowtype'), false, 'arrowType', null, true);
            this.addDropDownArrow(arrowTypeMenu, 'geSprite-arrowtype', 44, 50, 0, 0, 22, -4);
            /**
            const edgeShapeMenu = this.edgeShapeMenu = this.addMenu('', mxResources.get('connection'), false, 'edgeShape', null, true);
            this.addDropDownArrow(edgeShapeMenu, 'geSprite-arrowtype', 44, 50, 0, 0, 22, -4);
             */
            const edgeStyleMenu = this.edgeStyleMenu = this.addMenu('geSprite-orthogonal', mxResources.get('edgeStyle'), false, 'edgeStyle', null, true);
            this.addDropDownArrow(edgeStyleMenu, 'geSprite-edgestyle', 44, 50, 0, 0, 22, -4);
        }

        this.addSeparator();

        // 布局
        const layoutMenu = this.addMenu('', mxResources.get('layout'), true, 'layout', null, true);
        this.addDropDownArrow(layoutMenu, 'geSprite-layout', 38, 50, -4, -3, 36, -8);

        // 对齐方式
        const alignTypeMenu = this.addMenu('', mxResources.get('alignType'), true, 'alignType', null, true);
        this.addDropDownArrow(alignTypeMenu, 'geSprite-aligntype', 38, 50, -4, -3, 36, -8);

        this.addSeparator();

    }


    // if(isFzPage) {
    //     // 仿真界面功能按钮
    //     this.addItems(['simulatCompileRun', '-']);  //编译/生成/运行
    //     //this.addItems(['simulatStart', '-']);       //开始
    //     // TODO 实现暂停 和 继续
    //     this.addItems(['simulatSuspend', '-']);     //暂停
    //     this.addItems(['simulatRecover', '-']);     //恢复
    //     //this.addItems(['simulatSingle', '-']);      //单步
    //     this.addItems(['simulatOver', '-']);        //结束
    //     //this.addItems(['simulatBreakpoint', '-']);  //断点
    // }
};

/**
 * 动态设置仿真页面的按钮。
 * 根据当前图表类型决定是否显示仿真相关的按钮。
 */
Toolbar.prototype.setFzPageMenu = function () {
    // 判断当前是否是序列图或状态图
    var isSequenceDiagram = queryModelIsSequenceDiagram();

    // 时序图才展示这个按钮（已注释的代码）
    // var isTimeSequence = await isTimeSequenceDiagram();

    // 如果是序列图且仿真按钮不存在，则创建按钮
    if (isSequenceDiagram && !this.fzButton) {
        // this.fzButton = this.addItems(['fangzhen', '-']);  暂时屏蔽
    }
    if (this.fzButton && !isSequenceDiagram) {
        this.fzButton[0].parentNode.removeChild(this.fzButton[0])
        this.fzButton[1].parentNode.removeChild(this.fzButton[1])
        this.fzButton = null
    }
};

/**
 * 设置UML页面的菜单按钮。
 * 根据时序图类型决定是否显示UML排序按钮。
 */
Toolbar.prototype.setUmlPageMenu = function () {
    // 时序图才展示这个按钮
    var isTimeSequence = isTimeSequenceDiagram();
    console.log('-------umlSort--------', isTimeSequence);

    // 如果是时序图，添加UML排序按钮
    if (isTimeSequence) {
        this.umlButton = this.addItems(['umlsort']);
    }

    // 如果不是时序图且存在UML按钮，则移除按钮
    if (this.umlButton && !isTimeSequence) {
        this.umlButton[0].parentNode.removeChild(this.fzButton[0])
        this.umlButton[1].parentNode.removeChild(this.fzButton[1])
        this.umlButton = null
    }
};
/**
 * 添加表格下拉菜单。
 * 提供表格相关的操作选项，包括插入/删除行列等功能。
 */
Toolbar.prototype.addTableDropDown = function () {
    this.addSeparator();

    // 已知问题：所有表格功能不支持撤销/重做操作
    // 已知问题：在quirks模式和IE8中，点击带文本的子菜单后会失去焦点，
    // 这是因为TD元素在这些浏览器中点击时会捕获焦点。
    // 注意：在mxPopupMenu中为图标项提供了变通方案。
    // 创建表格菜单元素，提供表格编辑功能
    var menuElt = this.addMenuFunction('geIcon geSprite geSprite-table', mxResources.get('table'), false, mxUtils.bind(this, function (menu) {
        // 获取图形编辑器实例
        var graph = this.editorUi.editor.graph;
        // 获取当前选中的单元格
        var cell = graph.getSelectionCell();

        if (!graph.isTableCell(cell) && !graph.isTableRow(cell) && !graph.isTable(cell)) {
            this.editorUi.menus.addInsertTableCellItem(menu);
        } else {
            var elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.insertTableColumn(cell, true);
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-insertcolumnbefore');
            elt.setAttribute('title', mxResources.get('insertColumnBefore'));

            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.insertTableColumn(cell, false);
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-insertcolumnafter');
            elt.setAttribute('title', mxResources.get('insertColumnAfter'));

            // 添加删除列的菜单项
            elt = menu.addItem('Delete column', null, mxUtils.bind(this, function () {
                if (cell != null) {
                    try {
                        graph.deleteTableColumn(cell);
                    } catch (e) {
                        this.editorUi.handleError(e);
                    }
                }
            }), null, 'geIcon geSprite geSprite-deletecolumn');
            elt.setAttribute('title', mxResources.get('deleteColumn'));

            // 添加在当前行前插入行的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.insertTableRow(cell, true);
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-insertrowbefore');
            elt.setAttribute('title', mxResources.get('insertRowBefore'));

            // 添加在当前行后插入行的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.insertTableRow(cell, false);
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-insertrowafter');
            elt.setAttribute('title', mxResources.get('insertRowAfter'));

            // 添加删除行的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.deleteTableRow(cell);
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-deleterow');
            elt.setAttribute('title', mxResources.get('deleteRow'));
        }
    }));

    menuElt.style.position = 'relative';
    menuElt.style.whiteSpace = 'nowrap';
    menuElt.style.overflow = 'hidden';
    menuElt.innerHTML = '<div class="geSprite geSprite-table" style="margin-left:-2px;"></div>' + this.dropdownImageHtml;
    menuElt.style.width = '30px';

    // Kennedy主题中项目大小的修正
    if (EditorUi.compactUi) {
        menuElt.getElementsByTagName('img')[0].style.left = '22px';
        menuElt.getElementsByTagName('img')[0].style.top = '5px';
    }

    // 获取插入菜单对象，用于启用状态同步
    var menu = this.editorUi.menus.get('insert');

    // 变通方案：处理扩展HTML对象时可能出现的非函数情况
    if (menu != null && typeof menuElt.setEnabled === 'function') {
        menu.addListener('stateChanged', function () {
            menuElt.setEnabled(menu.enabled);
        });
    }

    return menuElt;
};

/**
 * 为菜单添加下拉箭头。
 * 配置菜单元素的样式和布局，添加下拉箭头图标。
 *
 * @param {HTMLElement} menu - 要添加箭头的菜单元素
 * @param {string} sprite - 精灵图样式类名
 * @param {number} width - 菜单宽度
 * @param {number} atlasWidth - 图集宽度
 * @param {number} left - 左侧偏移量
 * @param {number} top - 顶部偏移量
 * @param {number} atlasDelta - 图集增量
 * @param {number} atlasLeft - 图集左侧偏移量
 */
Toolbar.prototype.addDropDownArrow = function (menu, sprite, width, atlasWidth, left, top, atlasDelta, atlasLeft) {
    // 设置图集增量的默认值
    atlasDelta = (atlasDelta != null) ? atlasDelta : 32;
    // 根据紧凑UI模式选择左侧偏移量
    left = (EditorUi.compactUi) ? left : atlasLeft;

    menu.style.whiteSpace = 'nowrap';
    menu.style.overflow = 'hidden';
    menu.style.position = 'relative';
    menu.innerHTML = '<div class="geSprite ' + sprite + '" style="margin-left:' + left + 'px;margin-top:' + top + 'px;"></div>' +
        this.dropdownImageHtml;
    menu.style.width = (atlasWidth - atlasDelta) + 'px';

    // Kennedy主题中项目大小的修正
    if (EditorUi.compactUi) {
        menu.getElementsByTagName('img')[0].style.left = '24px';
        menu.getElementsByTagName('img')[0].style.top = '5px';
        menu.style.width = (width - 10) + 'px';
    }
};

/**
 * 设置当前字体名称。
 * 更新字体菜单的显示文本。
 *
 * @param {string} value - 要设置的字体名称
 */
Toolbar.prototype.setFontName = function (value) {
    if (this.fontMenu != null) {
        this.fontMenu.innerHTML = '<div style="width:60px;overflow:hidden;display:inline-block;">' +
            mxUtils.htmlEntities(value) + '</div>' + this.dropdownImageHtml;
    }
};

/**
 * 设置当前字体大小。
 * 更新字体大小菜单的显示文本。
 *
 * @param {string} value - 要设置的字体大小
 */
Toolbar.prototype.setFontSize = function (value) {
    if (this.sizeMenu != null) {
        this.sizeMenu.innerHTML = '<div style="width:24px;overflow:hidden;display:inline-block;">' +
            mxUtils.htmlEntities(value) + '</div>' + this.dropdownImageHtml;
    }
};

/**
 * 创建文本工具栏。
 * 为文本编辑功能提供字体、样式、对齐等工具按钮。
 */
Toolbar.prototype.createTextToolbar = function () {
    // 获取图形编辑器实例
    var graph = this.editorUi.editor.graph;

    // 创建样式菜单，用于选择文本样式
    var styleElt = this.addMenu('', mxResources.get('style'), true, 'formatBlock');
    styleElt.style.position = 'relative';
    styleElt.style.whiteSpace = 'nowrap';
    styleElt.style.overflow = 'hidden';
    styleElt.innerHTML = mxResources.get('style') + this.dropdownImageHtml;

    if (EditorUi.compactUi) {
        styleElt.style.paddingRight = '18px';
        styleElt.getElementsByTagName('img')[0].style.right = '1px';
        styleElt.getElementsByTagName('img')[0].style.top = '5px';
    }

    this.addSeparator();

    // 创建字体选择菜单，用于选择文本字体
    this.fontMenu = this.addMenu('', mxResources.get('fontFamily'), true, 'fontFamily');
    this.fontMenu.style.position = 'relative';
    this.fontMenu.style.whiteSpace = 'nowrap';
    this.fontMenu.style.overflow = 'hidden';
    this.fontMenu.style.width = '60px';

    // 设置默认字体名称
    this.setFontName(Menus.prototype.defaultFont);

    if (EditorUi.compactUi) {
        this.fontMenu.style.paddingRight = '18px';
        this.fontMenu.getElementsByTagName('img')[0].style.right = '1px';
        this.fontMenu.getElementsByTagName('img')[0].style.top = '5px';
    }

    this.addSeparator();

    // 创建字体大小选择菜单，用于设置文本字体大小
    this.sizeMenu = this.addMenu(Menus.prototype.defaultFontSize, mxResources.get('fontSize'), true, 'fontSize');
    this.sizeMenu.style.position = 'relative';
    this.sizeMenu.style.whiteSpace = 'nowrap';
    this.sizeMenu.style.overflow = 'hidden';
    this.sizeMenu.style.width = '24px';

    // 设置默认字体大小
    this.setFontSize(Menus.prototype.defaultFontSize);

    if (EditorUi.compactUi) {
        this.sizeMenu.style.paddingRight = '18px';
        this.sizeMenu.getElementsByTagName('img')[0].style.right = '1px';
        this.sizeMenu.getElementsByTagName('img')[0].style.top = '5px';
    }

    // 创建文本格式化按钮（撤销、重做、粗体、斜体、下划线）
    var elts = this.addItems(['-', 'undo', 'redo', '-', 'bold', 'italic', 'underline']);
    elts[1].setAttribute('title', mxResources.get('undo') + ' (' + this.editorUi.actions.get('undo').shortcut + ')');
    elts[2].setAttribute('title', mxResources.get('redo') + ' (' + this.editorUi.actions.get('redo').shortcut + ')');
    elts[4].setAttribute('title', mxResources.get('bold') + ' (' + this.editorUi.actions.get('bold').shortcut + ')');
    elts[5].setAttribute('title', mxResources.get('italic') + ' (' + this.editorUi.actions.get('italic').shortcut + ')');
    elts[6].setAttribute('title', mxResources.get('underline') + ' (' + this.editorUi.actions.get('underline').shortcut + ')');

    // 已知问题：在quirks模式和IE8中，点击带文本的子菜单后会失去焦点，
    // 这是因为TD元素在这些浏览器中点击时会捕获焦点。
    // 注意：在mxPopupMenu中为图标项提供了变通方案。
    // 创建文本对齐菜单，提供左对齐、居中、右对齐等选项
    var alignMenu = this.addMenuFunction('', mxResources.get('align'), false, mxUtils.bind(this, function (menu) {
        elt = menu.addItem('', null, mxUtils.bind(this, function (evt) {
            graph.cellEditor.alignText(mxConstants.ALIGN_LEFT, evt);
        }), null, 'geIcon geSprite geSprite-left');
        elt.setAttribute('title', mxResources.get('left'));

        elt = menu.addItem('', null, mxUtils.bind(this, function (evt) {
            graph.cellEditor.alignText(mxConstants.ALIGN_CENTER, evt);
        }), null, 'geIcon geSprite geSprite-center');
        elt.setAttribute('title', mxResources.get('center'));

        elt = menu.addItem('', null, mxUtils.bind(this, function (evt) {
            graph.cellEditor.alignText(mxConstants.ALIGN_RIGHT, evt);
        }), null, 'geIcon geSprite geSprite-right');
        elt.setAttribute('title', mxResources.get('right'));

        elt = menu.addItem('', null, mxUtils.bind(this, function () {
            document.execCommand('justifyfull', false, null);
        }), null, 'geIcon geSprite geSprite-justifyfull');
        elt.setAttribute('title', mxResources.get('justifyfull'));

        elt = menu.addItem('', null, mxUtils.bind(this, function () {
            document.execCommand('insertorderedlist', false, null);
        }), null, 'geIcon geSprite geSprite-orderedlist');
        elt.setAttribute('title', mxResources.get('numberedList'));

        elt = menu.addItem('', null, mxUtils.bind(this, function () {
            document.execCommand('insertunorderedlist', false, null);
        }), null, 'geIcon geSprite geSprite-unorderedlist');
        elt.setAttribute('title', mxResources.get('bulletedList'));

        elt = menu.addItem('', null, mxUtils.bind(this, function () {
            document.execCommand('outdent', false, null);
        }), null, 'geIcon geSprite geSprite-outdent');
        elt.setAttribute('title', mxResources.get('decreaseIndent'));

        elt = menu.addItem('', null, mxUtils.bind(this, function () {
            document.execCommand('indent', false, null);
        }), null, 'geIcon geSprite geSprite-indent');
        elt.setAttribute('title', mxResources.get('increaseIndent'));
    }));

    alignMenu.style.position = 'relative';
    alignMenu.style.whiteSpace = 'nowrap';
    alignMenu.style.overflow = 'hidden';
    alignMenu.innerHTML = '<div class="geSprite geSprite-left" style="margin-left:-2px;"></div>' + this.dropdownImageHtml;
    alignMenu.style.width = '30px';

    if (EditorUi.compactUi) {
        alignMenu.getElementsByTagName('img')[0].style.left = '22px';
        alignMenu.getElementsByTagName('img')[0].style.top = '5px';
    }

    // 创建文本格式菜单，提供上标、下标、字体颜色、背景色等格式化选项
    var formatMenu = this.addMenuFunction('', mxResources.get('format'), false, mxUtils.bind(this, function (menu) {
        elt = menu.addItem('', null, this.editorUi.actions.get('subscript').funct,
            null, 'geIcon geSprite geSprite-subscript');
        elt.setAttribute('title', mxResources.get('subscript') + ' (' + Editor.ctrlKey + '+,)');

        elt = menu.addItem('', null, this.editorUi.actions.get('superscript').funct,
            null, 'geIcon geSprite geSprite-superscript');
        elt.setAttribute('title', mxResources.get('superscript') + ' (' + Editor.ctrlKey + '+.)');

        // 已知问题：IE+FF在颜色对话框后不会返回键盘焦点（调用focus也没有帮助）
        elt = menu.addItem('', null, this.editorUi.actions.get('fontColor').funct,
            null, 'geIcon geSprite geSprite-fontcolor');
        elt.setAttribute('title', mxResources.get('fontColor'));

        elt = menu.addItem('', null, this.editorUi.actions.get('backgroundColor').funct,
            null, 'geIcon geSprite geSprite-fontbackground');
        elt.setAttribute('title', mxResources.get('backgroundColor'));

        elt = menu.addItem('', null, mxUtils.bind(this, function () {
            document.execCommand('removeformat', false, null);
        }), null, 'geIcon geSprite geSprite-removeformat');
        elt.setAttribute('title', mxResources.get('removeFormat'));
    }));

    formatMenu.style.position = 'relative';
    formatMenu.style.whiteSpace = 'nowrap';
    formatMenu.style.overflow = 'hidden';
    formatMenu.innerHTML = '<div class="geSprite geSprite-dots" style="margin-left:-2px;"></div>' +
        this.dropdownImageHtml;
    formatMenu.style.width = '30px';

    if (EditorUi.compactUi) {
        formatMenu.getElementsByTagName('img')[0].style.left = '22px';
        formatMenu.getElementsByTagName('img')[0].style.top = '5px';
    }

    this.addSeparator();

    // 添加HTML源码查看按钮
    this.addButton('geIcon geSprite geSprite-code', mxResources.get('html'), function () {
        graph.cellEditor.toggleViewMode();

        if (graph.cellEditor.textarea.innerHTML.length > 0 && (graph.cellEditor.textarea.innerHTML != '&nbsp;' || !graph.cellEditor.clearOnChange)) {
            window.setTimeout(function () {
                document.execCommand('selectAll', false, null);
            });
        }
    });

    this.addSeparator();

    // 创建插入菜单，提供插入链接、图片、水平线等功能
    var insertMenu = this.addMenuFunction('', mxResources.get('insert'), true, mxUtils.bind(this, function (menu) {
        menu.addItem(mxResources.get('insertLink'), null, mxUtils.bind(this, function () {
            this.editorUi.actions.get('link').funct();
        }));

        menu.addItem(mxResources.get('insertImage'), null, mxUtils.bind(this, function () {
            this.editorUi.actions.get('image').funct();
        }));

        menu.addItem(mxResources.get('insertHorizontalRule'), null, mxUtils.bind(this, function () {
            document.execCommand('inserthorizontalrule', false, null);
        }));
    }));

    insertMenu.style.whiteSpace = 'nowrap';
    insertMenu.style.overflow = 'hidden';
    insertMenu.style.position = 'relative';
    insertMenu.innerHTML = '<div class="geSprite geSprite-plus" style="margin-left:-4px;margin-top:-3px;"></div>' +
        this.dropdownImageHtml;
    insertMenu.style.width = '16px';

    // Kennedy主题中项目大小的修正
    if (EditorUi.compactUi) {
        insertMenu.getElementsByTagName('img')[0].style.left = '24px';
        insertMenu.getElementsByTagName('img')[0].style.top = '5px';
        insertMenu.style.width = '30px';
    }

    this.addSeparator();

    // 已知问题：所有表格功能不支持撤销/重做操作
    // 已知问题：在quirks模式和IE8中，点击带文本的子菜单后会失去焦点，
    // 这是因为TD元素在这些浏览器中点击时会捕获焦点。
    // 注意：在mxPopupMenu中为图标项提供了变通方案。
    // 创建文本编辑器中的表格菜单
    var elt = this.addMenuFunction('geIcon geSprite geSprite-table', mxResources.get('table'), false, mxUtils.bind(this, function (menu) {
        // 获取当前选中的DOM元素
        var elt = graph.getSelectedElement();
        // 获取父级表格单元格元素（TD或TH）
        var cell = graph.getParentByNames(elt, ['TD', 'TH'], graph.cellEditor.text2);
        // 获取父级表格行元素（TR）
        var row = graph.getParentByName(elt, 'TR', graph.cellEditor.text2);

        if (row == null) {
            /**
             * 创建表格HTML字符串的内部辅助函数。
             * 根据指定的行数和列数生成HTML表格结构。
             *
             * @param {number} rows - 表格的行数
             * @param {number} cols - 表格的列数
             * @returns {string} 生成的HTML表格字符串
             */
            function createTable(rows, cols) {
                // 初始化HTML数组，包含表格开始标签
                // HTML数组用于构建完整的表格HTML字符串
                var html = ['<table>'];

                // 循环创建每一行
                for (var i = 0; i < rows; i++) {
                    html.push('<tr>');

                    // 在每一行中循环创建每一列
                    for (var j = 0; j < cols; j++) {
                        html.push('<td><br></td>');
                    }

                    html.push('</tr>');
                }

                html.push('</table>');

                return html.join('');
            };

            this.editorUi.menus.addInsertTableItem(menu);
        } else {
            // 获取父级表格元素（TABLE）
            var table = graph.getParentByName(row, 'TABLE', graph.cellEditor.text2);

            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.selectNode(graph.insertColumn(table, (cell != null) ? cell.cellIndex : 0));
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-insertcolumnbefore');
            elt.setAttribute('title', mxResources.get('insertColumnBefore'));

            // 添加在当前单元格后插入列的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.selectNode(graph.insertColumn(table, (cell != null) ? cell.cellIndex + 1 : -1));
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-insertcolumnafter');
            elt.setAttribute('title', mxResources.get('insertColumnAfter'));

            elt = menu.addItem('Delete column', null, mxUtils.bind(this, function () {
                if (cell != null) {
                    try {
                        graph.deleteColumn(table, cell.cellIndex);
                    } catch (e) {
                        this.editorUi.handleError(e);
                    }
                }
            }), null, 'geIcon geSprite geSprite-deletecolumn');
            elt.setAttribute('title', mxResources.get('deleteColumn'));

            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.selectNode(graph.insertRow(table, row.sectionRowIndex));
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-insertrowbefore');
            elt.setAttribute('title', mxResources.get('insertRowBefore'));

            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.selectNode(graph.insertRow(table, row.sectionRowIndex + 1));
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-insertrowafter');
            elt.setAttribute('title', mxResources.get('insertRowAfter'));

            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                try {
                    graph.deleteRow(table, row.sectionRowIndex);
                } catch (e) {
                    this.editorUi.handleError(e);
                }
            }), null, 'geIcon geSprite geSprite-deleterow');
            elt.setAttribute('title', mxResources.get('deleteRow'));

            // 添加设置边框颜色的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                // 转换rgb(r,g,b)颜色值为十六进制格式
                // 获取表格边框颜色，并将其从rgb格式转换为十六进制格式
                var color = table.style.borderColor.replace(
                    /\brgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,
                    function ($0, $1, $2, $3) {
                        // 将rgb值转换为十六进制，并确保两位数格式
                        return "#" + ("0" + Number($1).toString(16)).substr(-2) + ("0" + Number($2).toString(16)).substr(-2) + ("0" + Number($3).toString(16)).substr(-2);
                    });
                this.editorUi.pickColor(color, function (newColor) {
                    if (newColor == null || newColor == mxConstants.NONE) {
                        table.removeAttribute('border');
                        table.style.border = '';
                        table.style.borderCollapse = '';
                    } else {
                        table.setAttribute('border', '1');
                        table.style.border = '1px solid ' + newColor;
                        table.style.borderCollapse = 'collapse';
                    }
                });
            }), null, 'geIcon geSprite geSprite-strokecolor');
            elt.setAttribute('title', mxResources.get('borderColor'));

            // 添加设置背景颜色的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                // 转换rgb(r,g,b)颜色值为十六进制格式
                // 获取表格背景颜色，并将其从rgb格式转换为十六进制格式
                var color = table.style.backgroundColor.replace(
                    /\brgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,
                    function ($0, $1, $2, $3) {
                        // 将rgb值转换为十六进制，并确保两位数格式
                        return "#" + ("0" + Number($1).toString(16)).substr(-2) + ("0" + Number($2).toString(16)).substr(-2) + ("0" + Number($3).toString(16)).substr(-2);
                    });
                this.editorUi.pickColor(color, function (newColor) {
                    if (newColor == null || newColor == mxConstants.NONE) {
                        table.style.backgroundColor = '';
                    } else {
                        table.style.backgroundColor = newColor;
                    }
                });
            }), null, 'geIcon geSprite geSprite-fillcolor');
            elt.setAttribute('title', mxResources.get('backgroundColor'));

            // 添加设置单元格间距的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                // 获取表格的单元格内边距值
                var value = table.getAttribute('cellPadding') || 0;

                // 创建文件名对话框，用于设置表格单元格间距
                var dlg = new FilenameDialog(this.editorUi, value, mxResources.get('apply'), mxUtils.bind(this, function (newValue) {
                    if (newValue != null && newValue.length > 0) {
                        table.setAttribute('cellPadding', newValue);
                    } else {
                        table.removeAttribute('cellPadding');
                    }
                }), mxResources.get('spacing'));
                this.editorUi.showDialog(dlg.container, 300, 80, true, true);
                dlg.init();
            }), null, 'geIcon geSprite geSprite-fit');
            elt.setAttribute('title', mxResources.get('spacing'));

            // 添加左对齐表格的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                table.setAttribute('align', 'left');
            }), null, 'geIcon geSprite geSprite-left');
            elt.setAttribute('title', mxResources.get('left'));

            // 添加居中对齐表格的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                table.setAttribute('align', 'center');
            }), null, 'geIcon geSprite geSprite-center');
            elt.setAttribute('title', mxResources.get('center'));

            // 添加右对齐表格的菜单项
            elt = menu.addItem('', null, mxUtils.bind(this, function () {
                table.setAttribute('align', 'right');
            }), null, 'geIcon geSprite geSprite-right');
            elt.setAttribute('title', mxResources.get('right'));
        }
    }));

    // 配置表格菜单元素的样式
    elt.style.position = 'relative';
    elt.style.whiteSpace = 'nowrap';
    elt.style.overflow = 'hidden';
    elt.innerHTML = '<div class="geSprite geSprite-table" style="margin-left:-2px;"></div>' + this.dropdownImageHtml;
    elt.style.width = '30px';

    // Kennedy主题中项目大小的修正
    if (EditorUi.compactUi) {
        elt.getElementsByTagName('img')[0].style.left = '22px';
        elt.getElementsByTagName('img')[0].style.top = '5px';
    }
};

/**
 * 隐藏当前菜单。
 * 通过编辑器UI关闭当前显示的菜单。
 */
Toolbar.prototype.hideMenu = function () {
    this.editorUi.hideCurrentMenu();
};

/**
 * 向工具栏添加菜单。
 * 创建一个菜单按钮，该按钮会触发指定的菜单功能。
 *
 * @param {string} label - 菜单标签文本
 * @param {string} tooltip - 工具提示文本
 * @param {boolean} showLabels - 是否显示标签
 * @param {string} name - 菜单名称
 * @param {HTMLElement} c - 容器元素
 * @param {boolean} showAll - 是否显示所有项
 * @param {boolean} ignoreState - 是否忽略状态变化
 * @returns {HTMLElement} 创建的菜单元素
 */
Toolbar.prototype.addMenu = function (label, tooltip, showLabels, name, c, showAll, ignoreState) {
    // 获取指定名称的菜单对象
    var menu = this.editorUi.menus.get(name);
    // 创建菜单功能按钮
    var elt = this.addMenuFunction(label, tooltip, showLabels, function () {
        menu.funct.apply(menu, arguments);
    }, c, showAll);

    // 变通方案：处理扩展HTML对象时可能出现的非函数情况
    if (!ignoreState && typeof elt.setEnabled === 'function') {
        elt.setEnabled(menu.enabled)
        menu.addListener('stateChanged', function () {
            elt.setEnabled(menu.enabled);
        });
    }

    return elt;
};

/**
 * 添加菜单功能到工具栏。
 * 创建一个菜单按钮，该按钮会执行指定的回调函数。
 *
 * @param {string} label - 菜单标签文本
 * @param {string} tooltip - 工具提示文本
 * @param {boolean} showLabels - 是否显示标签
 * @param {Function} funct - 点击时执行的回调函数
 * @param {HTMLElement} c - 容器元素
 * @param {boolean} showAll - 是否显示所有项
 * @returns {HTMLElement} 创建的菜单元素
 */
Toolbar.prototype.addMenuFunction = function (label, tooltip, showLabels, funct, c, showAll) {
    return this.addMenuFunctionInContainer((c != null) ? c : this.container, label, tooltip, showLabels, funct, showAll);
};

/**
 * 在指定容器中添加菜单功能。
 * 创建菜单元素并添加到指定的容器中。
 *
 * @param {HTMLElement} container - 要添加菜单的容器元素
 * @param {string} label - 菜单标签文本
 * @param {string} tooltip - 工具提示文本
 * @param {boolean} showLabels - 是否显示标签
 * @param {Function} funct - 点击时执行的回调函数
 * @param {boolean} showAll - 是否显示所有项
 * @returns {HTMLElement} 创建的菜单元素
 */
Toolbar.prototype.addMenuFunctionInContainer = function (container, label, tooltip, showLabels, funct, showAll) {
    // 根据是否显示标签选择创建标签或按钮元素
    var elt = (showLabels) ? this.createLabel(label) : this.createButton(label);
    // 初始化元素（设置工具提示等）
    this.initElement(elt, tooltip);
    // 添加菜单处理器
    this.addMenuHandler(elt, showLabels, funct, showAll);
    // 将元素添加到容器中
    container.appendChild(elt);

    return elt;
};

/**
 * 向工具栏添加分隔符。
 * 创建一个视觉分隔元素，用于分组工具栏按钮。
 *
 * @param {HTMLElement} c - 要添加分隔符的容器元素，默认使用工具栏容器
 * @returns {HTMLElement} 创建的分隔符元素
 */
Toolbar.prototype.addSeparator = function (c) {
    // 使用指定的容器，如果未指定则使用默认工具栏容器
    c = (c != null) ? c : this.container;
    // 创建分隔符div元素
    var elt = document.createElement('div');
    elt.className = 'geSeparator';
    // 将分隔符添加到容器中
    c.appendChild(elt);
    return elt;
};

/**
 * 向工具栏添加多个项目。
 * 根据提供的键数组批量创建工具栏项目，支持分隔符和操作项。
 *
 * @param {Array} keys - 要添加的项目键数组，'-'表示分隔符
 * @param {HTMLElement} c - 容器元素
 * @param {boolean} ignoreDisabled - 是否忽略禁用状态
 * @returns {Array} 创建的项目元素数组
 */
Toolbar.prototype.addItems = function (keys, c, ignoreDisabled) {
    // 存储创建的所有项目元素
    var items = [];
    // 遍历键数组，创建对应的项目
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        // 如果键是'-'，则添加分隔符
        if (key === '-') {
            items.push(this.addSeparator(c));
        } else {
            // 否则添加操作项，使用'geSprite-'前缀构建精灵图类名
            items.push(this.addItem('geSprite-' + key.toLowerCase(), key, c, ignoreDisabled));
        }
    }
    return items;
};

/**
 * 添加指定的操作项到工具栏。
 * 根据操作键创建对应的工具栏按钮，并绑定相应的功能。
 *
 * @param {string} sprite - 按钮的精灵图样式类名
 * @param {string} key - 操作的键名，用于获取对应的操作对象
 * @param {HTMLElement} c - 容器元素
 * @param {boolean} ignoreDisabled - 是否忽略禁用状态
 * @returns {HTMLElement} 创建的按钮元素，如果操作不存在则返回null
 */
Toolbar.prototype.addItem = function (sprite, key, c, ignoreDisabled) {
    // 从编辑器UI获取指定键的操作对象
    var action = this.editorUi.actions.get(key);
    var elt = null;

    if (action != null) {
        // 构建工具提示文本，包含操作标签和快捷键
        var tooltip = action.label;

        // 如果操作有快捷键，将其添加到工具提示中
        action.shortcut && (tooltip += ' (' + action.shortcut + ')');
        if (action.shortcut != null) {}

        // 创建按钮并绑定操作功能
        elt = this.addButton(sprite, tooltip, action.funct, c);

        // 变通方案：处理扩展HTML对象时可能出现的非函数情况
        if (!ignoreDisabled && typeof elt.setEnabled === 'function') {
            elt.setEnabled(action.enabled);
            action.addListener('stateChanged', function () {
                elt.setEnabled(action.enabled);
            });
        }
    }

    return elt;
};

/**
 * 向工具栏添加按钮。
 * 创建一个按钮元素并配置其样式、工具提示和点击事件。
 *
 * @param {string} classname - 按钮的CSS类名，用于设置按钮样式
 * @param {string} tooltip - 按钮的工具提示文本
 * @param {Function} funct - 按钮点击时执行的回调函数
 * @param {HTMLElement} c - 要添加按钮的容器元素，默认使用工具栏容器
 * @returns {HTMLElement} 创建的按钮元素
 */
Toolbar.prototype.addButton = function (classname, tooltip, funct, c) {
    // 创建按钮元素
    var elt = this.createButton(classname);
    // 使用指定的容器，如果未指定则使用默认工具栏容器
    c = (c != null) ? c : this.container;
    // 初始化元素（设置工具提示等）
    this.initElement(elt, tooltip);
    // 添加点击事件处理器
    this.addClickHandler(elt, funct);
    // 将按钮添加到容器中
    c.appendChild(elt);
    return elt;
};

/**
 * 初始化指定的工具栏元素。
 * 设置元素的工具提示和启用状态。
 *
 * @param {HTMLElement} elt - 要初始化的元素
 * @param {string} tooltip - 要设置的工具提示文本
 */
Toolbar.prototype.initElement = function (elt, tooltip) {
    // 添加工具提示
    if (tooltip != null) {
        elt.setAttribute('title', tooltip);
    }

    // 添加启用状态管理
    this.addEnabledState(elt);
};

/**
 * 为DOM节点添加启用状态和设置器（避免JS包装器）。
 * 通过修改CSS类名来控制元素的启用/禁用状态。
 *
 * @param {HTMLElement} elt - 要添加启用状态的元素
 */
Toolbar.prototype.addEnabledState = function (elt) {
    // 保存原始的CSS类名
    var classname = elt.className;

    // 为元素添加setEnabled方法
    elt.setEnabled = function (value) {
        elt.enabled = value;

        if (value) {
            // 启用状态：恢复原始类名
            elt.className = classname;
        } else {
            // 禁用状态：添加禁用样式类
            elt.className = classname + ' mxDisabled';
        }
    };

    // 初始化为启用状态
    elt.setEnabled(true);
};

/**
 * 为元素添加点击事件处理器。
 * 绑定点击事件，并在元素启用时执行指定的回调函数。
 *
 * @param {HTMLElement} elt - 要添加点击处理器的元素
 * @param {Function} funct - 点击时执行的回调函数
 */
Toolbar.prototype.addClickHandler = function (elt, funct) {
    if (funct != null) {
        // 添加点击事件监听器
        mxEvent.addListener(elt, 'click', function (evt) {
            // 只有在元素启用状态下才执行回调函数
            if (elt.enabled) {
                funct(evt);
            }

            // 阻止事件冒泡
            mxEvent.consume(evt);
        });

        // 防止焦点获取（通过阻止mousedown事件）
        mxEvent.addListener(elt, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown',
            mxUtils.bind(this, function (evt) {
                evt.preventDefault();
            }));
    }
};

/**
 * 创建并返回一个新的按钮元素。
 * 根据传入的类名创建具有特定样式的按钮，支持各种工具栏按钮的定制显示。
 *
 * @param {string} classname - 按钮的CSS类名，用于确定按钮的样式和功能
 * @returns {HTMLElement} 创建的按钮元素
 */
Toolbar.prototype.createButton = function (classname) {
    // 创建链接元素作为按钮容器
    var elt = document.createElement('a');
    // 将类名转换为小写作为元素ID
    var id = classname.toString().toLowerCase();
    elt.id = id;
    elt.className = 'geButton';

    // 创建内部div元素用于容纳按钮内容
    var inner = document.createElement('div');
    inner.style.padding = '1px';

    // 仿真相关按钮的特殊处理
    // 编译/生成/运行、开始、暂停、恢复、单步、结束、断点
    if (id === 'gesprite-simulatcompilerun') {
        inner.innerText = '编译/生成/运行';
    } else if (id === 'gesprite-fangzhen') {
        inner.innerText = '仿真';
    } else if (id === 'gesprite-umlsort') {
        inner.innerText = '排序';
    } else if (id === 'gesprite-simulatstart') {
        inner.innerText = '开始';
        inner.style.padding = '1px';
    } else if (id === 'gesprite-simulatsuspend') {
        inner.innerText = '暂停';
        inner.style.padding = '1px';
    } else if (id === 'gesprite-simulatrecover') {
        inner.innerText = '恢复';
    } else if (id === 'gesprite-simulatsingle') {
        inner.innerText = '单步';
    } else if (id === 'gesprite-simulatover') {
        inner.innerText = '结束';
    } else if (id === 'gesprite-simulatbreakpoint') {
        inner.innerText = '断点';
    } else if (id === "gesprite-timesequencetostate") {
        inner.innerText = '辅助生成';
    } else {
        if (classname) {
            inner.className = 'geSprite ' + classname;
        }
    }

    elt.appendChild(inner);

    return elt;

};

/**
 * 工具栏菜单缓存对象。
 * 用于存储和管理工具栏中使用的菜单实例。
 */
Toolbar.prototype.menus = {};

/**
 * 向菜单缓存中添加菜单项。
 * 将指定的键值对存储到工具栏的菜单缓存中。
 *
 * @param {string} a - 菜单项的键名
 * @param {*} b - 要存储的菜单对象
 * @returns {*} 返回存储的菜单对象
 */
Toolbar.prototype.put = function (a, b) {
    this.menus[a] = b;
    return b;
};

/**
 * 从菜单缓存中获取菜单项。
 * 根据指定的名称从工具栏的菜单缓存中检索菜单对象。
 *
 * @param {string} name - 要获取的菜单项名称
 * @returns {*} 返回找到的菜单对象，如果不存在则返回undefined
 */
Toolbar.prototype.get = function (name) {
    return this.menus[name];
};
/**
 * 创建并返回一个新的标签元素。
 * 用于在工具栏中显示文本标签。
 *
 * @param {string} label - 要显示的标签文本
 * @returns {HTMLElement} 创建的标签元素
 */
Toolbar.prototype.createLabel = function (label) {
    // 创建链接元素作为标签容器
    var elt = document.createElement('a');
    elt.className = 'geLabel';
    // 将文本写入元素
    mxUtils.write(elt, label);

    return elt;
};

/**
 * 为指定元素添加菜单显示处理器。
 * 当元素被点击时显示相应的菜单。
 *
 * @param {HTMLElement} elt - 要添加菜单处理器的元素
 * @param {boolean} showLabels - 是否在菜单中显示标签
 * @param {Function} funct - 用于填充菜单内容的回调函数
 * @param {boolean} showAll - 是否显示所有菜单项（包括禁用的）
 */
Toolbar.prototype.addMenuHandler = function (elt, showLabels, funct, showAll) {
    if (funct != null) {
        // 获取图形编辑器实例
        var graph = this.editorUi.editor.graph;
        var menu = null;
        // 控制菜单显示的标志
        var show = true;

        // 添加点击事件监听器
        mxEvent.addListener(elt, 'click', mxUtils.bind(this, function (evt) {
            if (show && (elt.enabled == null || elt.enabled)) {
                graph.popupMenuHandler.hideMenu();
                menu = new mxPopupMenu(funct);
                menu.div.className += ' geToolbarMenu';
                menu.showDisabled = showAll;
                menu.labels = showLabels;
                menu.autoExpand = true;

                var offset = mxUtils.getOffset(elt);
                menu.popup(offset.x, offset.y + elt.offsetHeight, null, evt);
                this.editorUi.setCurrentMenu(menu, elt);

                // 变通方案：防止滚动条隐藏菜单项
                if (!showLabels && menu.div.scrollHeight > menu.div.clientHeight) {
                    menu.div.style.width = '40px';
                }

                menu.hideMenu = mxUtils.bind(this, function () {
                    mxPopupMenu.prototype.hideMenu.apply(menu, arguments);
                    this.editorUi.resetCurrentMenu();
                    menu.destroy();
                });

                // 扩展销毁方法以重置全局状态
                menu.addListener(mxEvent.EVENT_HIDE, mxUtils.bind(this, function () {
                    this.currentElt = null;
                }));
            }

            show = true;
            mxEvent.consume(evt);
        }));

        // 如果菜单已在显示则隐藏，并防止焦点获取
        mxEvent.addListener(elt, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown',
            mxUtils.bind(this, function (evt) {
                show = this.currentElt != elt;
                evt.preventDefault();
            }));
    }
};

/**
 * 销毁工具栏实例。
 * 清理所有事件监听器和资源引用。
 */
Toolbar.prototype.destroy = function () {
    // 移除全局手势处理器
    if (this.gestureHandler != null) {
        mxEvent.removeGestureListeners(document, this.gestureHandler);
        this.gestureHandler = null;
    }
};